package com.chenailin.www.controller.article;

import com.chenailin.www.model.dto.ArticleDTO;
import com.chenailin.www.model.pojo.Article;
import com.chenailin.www.model.vo.ArticleVO;
import com.chenailin.www.model.vo.ResultVO;
import com.chenailin.www.service.ArticleService;
import com.chenailin.www.serviceimpl.ArticleServiceImpl;
import com.chenailin.www.util.JsonUtil;
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author evi
 */
@WebServlet("/article/*")
public class ArticleController extends HttpServlet {
    private final ArticleService articleService = new ArticleServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set response content type
        resp.setContentType("application/json;charset=UTF-8");
        String path = req.getRequestURI().substring(req.getContextPath().length());
        Long userId = (Long) req.getSession().getAttribute("userId");

        try {
            if (path.startsWith("/article/list/")) {
                // Get articles by knowledge base ID
                Long knowledgeBaseId = Long.parseLong(path.substring("/article/list/".length()));
                List<ArticleVO> articles = articleService.listArticlesByKnowledgeBase(knowledgeBaseId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(articles)));
            } else if (path.startsWith("/article/recent")) {
                // ！！！
//                // Get recent articles with pagination
//                int page = req.getParameter("page") != null ? Integer.parseInt(req.getParameter("page")) : 1;
//                int limit = req.getParameter("limit") != null ? Integer.parseInt(req.getParameter("limit")) : 10;
//                String sortBy = req.getParameter("sortBy") != null ? req.getParameter("sortBy") : "createTime";
//                boolean onlyFollowing = "true".equals(req.getParameter("onlyFollowing"));
//
//                List<ArticleVO> articles;
//                if (onlyFollowing) {
//                    articles = articleService.getFollowingUserArticles(userId, page, limit, sortBy);
//                } else {
//                    articles = articleService.getRecentArticles(page, limit, sortBy);
//                }
//
//                int total = articleService.countArticles(onlyFollowing ? userId : null);
//
//                Map<String, Object> result = new HashMap<>();
//                result.put("articles", articles);
//                result.put("total", total);
//                result.put("current", page);
//                result.put("size", limit);
//
//                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(result)));
                // Get recent articles
                int limit = req.getParameter("limit") != null ? Integer.parseInt(req.getParameter("limit")) : 10;
                List<ArticleVO> articles = articleService.getRecentArticles(limit, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(articles)));
            } else if (path.startsWith("/article/popular")) {
                // Get popular articles by likes
                int limit = req.getParameter("limit") != null ? Integer.parseInt(req.getParameter("limit")) : 10;
                List<ArticleVO> articles = articleService.getPopularArticles(limit);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(articles)));
            } else if (path.startsWith("/article/")) {
                // Get article by ID
                Long articleId = Long.parseLong(path.substring("/article/".length()));

                ArticleVO article = articleService.getArticleById(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(article)));
            } else {
                // Invalid path
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid request path")));
            }
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid ID format")));
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(500, e.getMessage())));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set response content type
        resp.setContentType("application/json;charset=UTF-8");
        Long userId = (Long) req.getSession().getAttribute("userId");
        String path = req.getRequestURI().substring(req.getContextPath().length());

        try {
            if (path.equals("/article")) {
                // Create new article
                ArticleDTO dto = JsonUtil.fromJson(IOUtils.toString(req.getReader()), ArticleDTO.class);
                Article article = articleService.createArticle(dto, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(article)));
            } else if (path.startsWith("/article/like/")) {
                Long articleId = Long.parseLong(path.substring("/article/like/".length()));
                articleService.likeArticle(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success("Article liked successfully")));
            } else if (path.startsWith("/article/unlike/")) {
                Long articleId = Long.parseLong(path.substring("/article/unlike/".length()));
                articleService.unlikeArticle(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success("Article unliked successfully")));
            } else if (path.startsWith("/article/favorite/")) {
                Long articleId = Long.parseLong(path.substring("/article/favorite/".length()));
                articleService.favoriteArticle(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success("Article favorited successfully")));
            } else if (path.startsWith("/article/unfavorite/")) {
                Long articleId = Long.parseLong(path.substring("/article/unfavorite/".length()));
                articleService.unfavoriteArticle(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success("Article unfavorited successfully")));
            } else {
                // Invalid path
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid request path")));
            }
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid ID format")));
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(500, e.getMessage())));
        }
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set response content type
        resp.setContentType("application/json;charset=UTF-8");
        String path = req.getRequestURI().substring(req.getContextPath().length());
        Long userId = (Long) req.getSession().getAttribute("userId");

        try {
            if (path.startsWith("/article/")) {
                Long articleId = Long.parseLong(path.substring("/article/".length()));
                ArticleDTO dto = JsonUtil.fromJson(IOUtils.toString(req.getReader()), ArticleDTO.class);
                Article updatedArticle = articleService.updateArticle(dto, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success(updatedArticle)));
            } else {
                // Invalid path
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid request path")));
            }
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid ID format")));
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(500, e.getMessage())));
        }
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set response content type
        resp.setContentType("application/json;charset=UTF-8");
        String path = req.getRequestURI().substring(req.getContextPath().length());
        Long userId = (Long) req.getSession().getAttribute("userId");

        try {
            if (path.startsWith("/article/")) {
                Long articleId = Long.parseLong(path.substring("/article/".length()));
                articleService.deleteArticle(articleId, userId);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.success("Article deleted successfully")));
            } else {
                // Invalid path
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid request path")));
            }
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid ID format")));
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(500, e.getMessage())));
        }
    }
}